package com.acme.chat.client;

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import com.acme.chat.message.ChatMessage;
import com.acme.chat.message.Message;
import com.acme.chat.message.MessageType;
import com.acme.chat.server.Server;

public class TcpGuiClient extends JFrame implements ActionListener, ClientListener {

    private JLabel label;
    private JTextField tf;
    private JTextField tfServer, tfPort, tfRoom;
    private JButton login, logout, list;
    private JTextArea ta;
    private boolean connected;
    private ChatClient client;
    private Server server;
    private int defaultPort;
    private String defaultHost;

    public TcpGuiClient(String host, int port) {

        super("Chat Client");
        defaultPort = port;
        defaultHost = host;

        JPanel northPanel = new JPanel(new GridLayout(3, 1));
        JPanel serverAndPort = new JPanel(new GridLayout(1, 5, 1, 3));
        tfServer = new JTextField(host);
        tfPort = new JTextField("" + port);
        tfPort.setHorizontalAlignment(SwingConstants.RIGHT);
        tfRoom = new JTextField("1");
        tfPort.setHorizontalAlignment(SwingConstants.CENTER);

        serverAndPort.add(new JLabel("Server:  "));
        serverAndPort.add(tfServer);
        serverAndPort.add(new JLabel("Port:  "));
        serverAndPort.add(tfPort);
        serverAndPort.add(new JLabel("Room:  "));
        serverAndPort.add(tfRoom);
        serverAndPort.add(new JLabel(""));
        northPanel.add(serverAndPort);

        label = new JLabel("Enter your username below", SwingConstants.CENTER);
        northPanel.add(label);
        tf = new JTextField("Anonymous");
        northPanel.add(tf);
        add(northPanel, BorderLayout.NORTH);

        ta = new JTextArea("Log of client's messages\n");
        JPanel centerPanel = new JPanel(new GridLayout(1, 1));
        centerPanel.add(new JScrollPane(ta));
        ta.setEditable(false);
        add(centerPanel, BorderLayout.CENTER);

        login = new JButton("Login");
        login.addActionListener(this);
        logout = new JButton("Logout");
        logout.addActionListener(this);
        logout.setEnabled(false);
        list = new JButton("List");
        list.addActionListener(this);
        list.setEnabled(false);

        JPanel southPanel = new JPanel();
        southPanel.add(login);
        southPanel.add(logout);
        southPanel.add(list);
        add(southPanel, BorderLayout.SOUTH);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600, 600);
        setVisible(true);
        tf.requestFocus();

    }

    void append(String str) {
        ta.append(str);
        ta.setCaretPosition(ta.getText().length() - 1);
    }

    void connectionFailed() {
        login.setEnabled(true);
        logout.setEnabled(false);
        list.setEnabled(false);
        label.setText("Enter your username below");
        // tf.setText("Anonymous");
        tfPort.setText("" + defaultPort);
        tfServer.setText(defaultHost);
        tfServer.setEditable(false);
        tfPort.setEditable(false);
        tf.removeActionListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        Object o = e.getSource();
        if (o == logout) {
            client.disconnect();
            connected = false;
            server = null;
            return;
        }
        if (o == list) {
            client.sendMessage(new ChatMessage(MessageType.WHOISIN, ""));
            return;
        }

        if (connected) {
            client.sendMessage(new ChatMessage(MessageType.MESSAGE, tf.getText()));
            tf.setText("");
            return;
        }

        if (o == login) {
            String username = tf.getText().trim();
            String room = tfRoom.getText().trim();
            if (username.length() == 0)
                return;
            String host = tfServer.getText().trim();
            if (host.length() == 0)
                return;
            String portNumber = tfPort.getText().trim();
            if (portNumber.length() == 0)
                return;
            defaultPort = Integer.parseInt(portNumber);

            if (client != null) {
                client.disconnect();
            }
            client = new ClientImpl(username, room);
            client.addListener(this);
            server = null;
            server = new TcpProxyServer(host, defaultPort);
            client.connect(server);
            tf.setText("");
            label.setText("Enter your message below");
            connected = true;
            login.setEnabled(false);
            logout.setEnabled(true);
            list.setEnabled(true);
            tfServer.setEditable(false);
            tfPort.setEditable(false);
            tf.addActionListener(this);
        }

    }

    public void onGetMessage(Message message) {
        this.append(message.getMessage());
    }

    public void onDisconnect() {
        this.connectionFailed();
    }

    public static void main(String[] args) {
        new TcpGuiClient("localhost", 1800);
    }

}
